local socket = require "socket"
local handler = require "handler"
local sproto = require "sproto"
local sprotoparser = require "sprotoparser"

local _M = {} 

local var = {
	fd = nil,
    session = 0, 
    session_map = {},
    host = nil, 
    request = nil, 
}

-- 客户端响应服务端的消息（请求REQ 或者 响应 RESP）
local function handle_package(t, ...)
	local arr = {...}
	if t == "REQUEST" then
		local name = arr[1]
		local args = arr[2]
		print(t, name, args)

		assert(handler.REQ_FROM_SERVER(name), "NOT REQ_FROM_SERVER handler found for: " .. name)
		local f = handler.REQ_FROM_SERVER(name)
		f(args)

	elseif t == "RESPONSE" then
		local session = arr[1]
		local args = arr[2]
		print(t, session, args)

		local name = session_map[session]
		if name then
			session_map[session] = nil

			assert(handler.RESP_FROM_SERVER(name), "NOT RESP_FROM_SERVER handler found for: " .. name)
			local f = handler.RESP_FROM_SERVER(name)
			f(args)
		end
	end
end

-- 加载客户端sproto协议
-- name=$ROOT
function _M.register_sproto(name)
    local f = assert(io.open(name .. "/proto/s2c.sproto", "r"))

    local s2c = f:read("*a")
    f:close()
    var.host = sproto.new(sprotoparser.parse(s2c)):host "package"

    local f = assert(io.open(name .. "/proto/c2s.sproto", "r"))
    local c2s = f:read("*a")
    f:close()
    var.request = var.host:attach(sproto.new(sprotoparser.parse(c2s)))
end

-- 客户端向服务端发送请求
function _M.send_request(name, args)
    var.session = var.session + 1
    var.session_map[var.session] = name 
    local str = var.request(name, args, var.session)
	socket.send_package(var.fd, str)
end

-- 分发服务端来的消息
function _M.dispatch_package()
	while true do
		local v = socket.try_read_package(var.fd)
		if not v then
			break
		end
		handle_package(var.host:dispatch(v))
	end
end

-- 当前message通信的句柄fd
function _M.set_fd(fd)
	var.fd = fd
end

return _M 